#include "generate.h"

#include "symbol.h"
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>

CppGenerate * 
CppGenerate::instance()
{
	static CppGenerate g;
	return &g;
}

CppGenerate::CppGenerate()
{
	directory("./cpp");
}

void 
CppGenerate::directory(std::string str)
{
	_directory = boost::filesystem::path(str); 
	boost::filesystem::create_directory(_directory);
}

void 
CppGenerate::make_code(Symbol * s)
{

	switch(s->type())
	{
	case Enum:
		make_define_enum(s);
		break;
	case Struct:
		make_define_struct(s);
		break;
	case Interface:
		make_define_interface(s);
	default:

		break;
	}

	std::ofstream out((_directory.string() + "/rpc.h").c_str());
	out<<"#ifndef __RPC_H__\n";
	out<<"#define __RPC_H__\n\n";
	out<<"#include<vector>\n";
	out<<"#include<string>\n";
	out<<"typedef char		Int8;\n";
	out<<"typedef short		Int16;\n";
	out<<"typedef int		Int32;\n";
	out<<"typedef long long Int64;\n";

	out<<"typedef unsigned char			UInt8;\n";
	out<<"typedef unsigned short		UInt16;\n";
	out<<"typedef unsigned int			UInt32;\n";
	out<<"typedef unsigned long long	UInt64;\n";

	out<<"typedef void		Void;\n";

	out<<"typedef std::string String;\n";

	out<<"#define Vector std::vector;\n";
	for(size_t i=0 ; i<_files.size() ; ++i)
	{
		out<<"#include \""<<_files[i]<<"\"\n";
	}
	out<<"\n#endif\n";
	out.close();
}

void 
CppGenerate::make_define_enum(Symbol *s)
{
	std::string name = s->name();
	std::string file_name = name + ".h";
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	_files.push_back(file_name);
	out<<"#ifndef __" << name.c_str() <<"__\n";
	out<<"#define __" << name.c_str() <<"__\n";
	
	out<<"enum " << name.c_str() <<"\n";
	out<<"{\n";	
	for( size_t i=0 ; i<s->get_attrs().size(); ++i)
	{
		out<<"\t"<<s->get_attrs()[i]->name().c_str()<<",\n";
	}
	out<<"};\n";

	out<<"#endif\n";
	out.close();
}

void 
CppGenerate::make_define_struct(Symbol *s)
{
	std::string file_name = s->name() + ".h";
	std::string target = _directory.string() + "/"+ file_name;
	
	std::ofstream out(target.c_str());
	_files.push_back(file_name);
	out<<"#ifndef __" << s->name() <<"_H__\n";
	out<<"#define __" << s->name() <<"_H__\n";

	out<<"struct " << s->name() <<"\n";
	out<<"{\n";
	
	std::string members;
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i<attrlist.size(); ++i)
	{
		members += "\t\t";
		make_define_member(attrlist[i],members);
		members += ";\n\n";
	}	
	make_serialize(s , members);
	make_deserialize(s , members);
	out<<members;
	
	out<<"};\n";

	out<<"#endif\n";
	out.close();
}

void
CppGenerate::make_define_interface(Symbol *s)
{
	make_proxy(s);
	make_stub(s);
}

void 
CppGenerate::make_proxy(Symbol *s)
{
	std::string  proxy_name =  s->name() + "_proxy";
	std::string file_name =  proxy_name + ".h";
	_files.push_back(file_name);
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	out<<"#ifndef __" << proxy_name <<"__\n";
	out<<"#define __" << proxy_name <<"__\n";

	out<<"template < typename Socket , typename Proxy >\n";
	out<<"class "<< proxy_name << "\n";
	out<<"{\n";
	out<<"public:\n";
	out<<"\tenum \n";
	out<<"\t{\n";
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i< attrlist.size(); ++i)
	{
		out<<"\t\t__"<<attrlist[i]->name()<<"__";
		if(i+1<attrlist.size())
		{
			out<<",\n";
		}
	}
	out<<"\n\t};\n";
	
	out<<"public:\n";
	out<<"\tvoid dispatch(Socket &__socket__)\n";
	out<<"\t{\n";
	out<<"\t Socket &__reader__ = __socket__ ;";
	out<<"\t\tUInt16 id = __reader__.readUInt16();\n";
	out<<"\t\tswitch(id)\n";
	out<<"\t\t{\n";
	for(size_t i=0 ; i<attrlist.size(); ++i)
	{
		out<<"\t\t\tcase __"<<attrlist[i]->name().c_str()<<"__ :\n";
		out<<"\t\t\t{\n";
		Symbol::AttrList const paramlist = attrlist[i]->get_attrs();
		for(size_t j=1 ; j<paramlist.size(); ++j)
		{
			std::string str_def ;
			make_define_member(paramlist[j],str_def);
			out<<"\t\t\t\t"<<str_def<<";\n\n";
			std::string str_des;
			make_deserialize_member(paramlist[j],str_des);
			out<<"\t\t\t\t"<<str_des<<"\n\n";
		}
		
		out<<"\t\t\t\t_proxy->"<<attrlist[i]->name()<<"( ";
		for(size_t j=1 ; j<paramlist.size(); ++j)
		{
			out<<paramlist[j]->name();
			if(j+1<paramlist.size())
			{
				out<<",";
			}
		}
		out<<" );\n";
		out<<"\t\t\t\tbreak;\n";
		out<<"\t\t\t}\n";
	}
	
	out<<"\t\t\tdefault:\n";
	out<<"\t\t\t{\n";
	out<<"\t\t\t\tbreak;\n";
	out<<"\t\t\t}\n";
	out<<"\t\t}\n";

	out<<"\t}\n";
	
	out<<"public:\n";
	out<<"\t"<<proxy_name.c_str()<<"(Proxy *proxy):_proxy(proxy){}\n";
	out<<"\t~"<<proxy_name.c_str()<<"(){}\n";
	out<<"private:\n";
	out<<"\tProxy *_proxy;\n";
	out<<"};\n";
	out<<"#endif\n";
	out.close();
}

void
CppGenerate::make_stub(Symbol *s)
{
	std::string  stub_name = s->name() + "_stub";
	std::string file_name =  stub_name + ".h";
	_files.push_back(file_name);
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	out<<"#ifndef __" << stub_name.c_str() <<"__\n";
	out<<"#define __" << stub_name.c_str() <<"__\n";
	
	out<<"template < typename Socket >\n";
	out<<"class "<<stub_name<<"\n";
	out<<"{\n";
	out<<"public:\n";
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i<attrlist.size();++i)
	{
		out<<"\tvoid "<<attrlist[i]->name().c_str()<<"(";
		Symbol::AttrList const paramlist = attrlist[i]->get_attrs();
		for(size_t j=1;j<paramlist.size();++j)
		{
			std::string str_def;
			make_define_member(paramlist[j],str_def);
			out<<str_def;
			if(j+1<paramlist.size())
			{
				out<<",";
			}
		}
		out<<")\n";

		out<<"\t{\n";
		out<<"\t\tSocket &__writer__ = *_socket;\n";
		out<<"\t\t__writer__.writeUInt16( "<< i <<" );\n";
		for(size_t j=1;j<paramlist.size();++j)
		{
			std::string str_def;
			make_serialize_member(paramlist[j],str_def);
			out<<"\t\t"<<str_def<<"\n";
		}
		out<<"\t}\n";

	}
	out<<"public:\n";
	out<<"\t"<<stub_name.c_str()<<"(Socket *socket):_socket(socket){}\n";
	out<<"\t~"<<stub_name.c_str()<<"(){}\n";
	out<<"private:\n";
	out<<"\tSocket *_socket;\n";
	out<<"};\n";
	out<<"#endif";
	out.close();
}

void 
CppGenerate::make_define_member(Symbol *s  , std::string &str)
{
	switch(s->type())
	{
	case None:
		{
			return;
		}
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			make_define_member(attrlist[0] , str);
			str += s->name();
			return;
		}
	case Custom:
		{
			str += s->name();
			str += " ";
			return;
		}
	case Boolean:
		{
			str += "Bool ";
			return;
		}
	case Void:
		{
			str += "Void ";
			return;
		}
	case Int8:
		{
			str += "Int8 ";
			return;
		}
	case Int16:
		{
			str += "Int16 ";
			return;
		}
	case Int32:
		{
			str += "Int32 ";
			break;
		}
	case Int64:
		{
			str += "Int64 ";
			return;
		}
	case UInt8:
		{
			str += "UInt8 ";
			return;
		}
	case UInt16:
		{
			str += "UInt16 ";
			return;
		}
	case UInt32:
		{
			str += "UInt32 ";
			return;
		}
	case UInt64:
		{
			str += "UInt64 ";
			return;
		}
	case String:
		{
			str += "String ";
			return;
		}
	case Vector:
		{
			str += "Vector < ";
			Symbol::AttrList const attrlist = s->get_attrs();
			make_define_member(attrlist[0] , str);
			str += " > ";
			return;
		}
	default:{	return;}
	}
}

void 
CppGenerate::make_serialize(Symbol *s, std::string & str)
{
	str += "template < typename T > void serialize( T & __writer__ ){";
	Symbol::AttrList const attrlist = s->get_attrs();

	std::string code ;
	for( size_t i=0 ; i<attrlist.size() ; ++i)
	{
		make_serialize_member(attrlist[i],code);
		str += code; 
		code = "";
	}
	str += "}\n";
}

void 
CppGenerate::make_serialize_member(Symbol *s, std::string & str)
{
	
	switch(s->type())
	{
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();

			str += s->name();
			make_serialize_member(attrlist[0] , str);
			return;
		}
	case Custom:
		{
			str += ".serialize( __writer__ );";
			return;
		}
	case Boolean:
		{
			str = "__writer__.writeBoolean( " + str + " ) ;";
			return;
		}
	case Int8:
		{
			str = "__writer__.writeInt8( " + str + " ) ;";
			return;
		}
	case Int16:
		{
			str = "__writer__.writeInt16( " + str + " ) ;";
			return;
		}
	case Int32:
		{
			str = "__writer__.writeInt32( " + str + " ) ;";
			break;
		}
	case Int64:
		{
			str = "__writer__.writeInt64( " + str + " ) ;";
			return;
		}
	case UInt8:
		{
			str = "__writer__.writeUInt8( " + str + " ) ;";
			return;
		}
	case UInt16:
		{
			str = "__writer__.writeUInt16( " + str + " ) ;";
			return;
		}
	case UInt32:
		{
			str = "__writer__.writeUInt32( " + str + " ) ;";
			return;
		}
	case UInt64:
		{
			str = "__writer__.writeUInt64( " + str + " ) ;";
			return;
		}
	case String:
		{
			std::string code = "__writer__.writeUInt16( " + str + ".size() );";
			code += "for( size_t i=0 ; i<" + str + ".size() ; ++i ) { ";
			code += "__writer__.writeUInt8( " + str + "[i] ) ;}";
			str = code;
			return;
		}	
	case Vector:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			static int i = 0;
			char buff[64] = {'\0'};
			std::string str_var = std::string("_")+std::string(::itoa(i++,buff,2))+std::string("_");
			std::string code = "__writer__.writeUInt16( " + str + ".size() );";
			code += "for( size_t " + str_var + " ; " + str_var + "<" + str + ".size() ; ++" + str_var + ")";
			code += "{";
			str = str + "["+ str_var +"]"; 
			make_serialize_member(attrlist[0],str);
			code += str;
			code += "}";

			str = code;
			break;
		}
	default:{	return;}
	}
}

void 
CppGenerate::make_deserialize(Symbol *s, std::string & str)
{
	str += "template < typename T > void deserialize( T & __reader__ ){";
	Symbol::AttrList const attrlist = s->get_attrs();

	std::string code ;
	for( size_t i=0 ; i<attrlist.size() ; ++i)
	{
		make_deserialize_member(attrlist[i],code);
		str += code; 
		code = "";
	}
	str += "}\n";
}

void 
CppGenerate::make_deserialize_member(Symbol *s, std::string & str)
{

	switch(s->type())
	{
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();

			str += s->name();
			make_deserialize_member(attrlist[0] , str);
			return;
		}
	case Custom:
		{
			str += ".deserialize( __reader__ );";
			return;
		}
	case Boolean:
		{
			str += " = __reader__.readBoolean() ;";
			return;
		}
	case Int8:
		{
			str += " = __reader__.readInt8() ;";
			return;
		}
	case Int16:
		{
			str += " = __reader__.readInt16() ;";
			return;
		}
	case Int32:
		{
			str += " = __reader__.readInt32() ;";
			break;
		}
	case Int64:
		{
			str += " = __reader__.readInt64() ;";
			return;
		}
	case UInt8:
		{
			str += " = __reader__.readUInt8() ;";
			return;
		}
	case UInt16:
		{
			str += " = __reader__.readUInt16() ;";
			return;
		}
	case UInt32:
		{
			str += " = __reader__.readUInt32() ;";
			return;
		}
	case UInt64:
		{
			str += " = __reader__.readUInt64() ;";
			return;
		}
	case String:
		{
			std::string code = "UInt16 size = __reader__.readUInt16();";
			code += str + ".resize( size );";
			code += "for( size_t i=0 ; i<size ; ++i ) {";
			code += str + "[i] = __reader__.readUInt8() ;}";
			str = code;
			return;
		}	
	case Vector:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			static int i = 0;
			char buff[64] = {'\0'};
			std::string str_size = std::string("_size_") +std::string(::itoa(i++,buff,2)) + std::string("_");
			std::string str_var = std::string("_")+std::string(::itoa(i++,buff,2))+std::string("_");
			std::string code = std::string("UInt16 ") + str_size + " = __reader__.readUInt16();";
			code += str + ".resize(size)";
			code += "for( size_t " + str_var + " ; " + str_var + "<"+ str_size +" ; ++" + str_var + ")";
			code += "{";
			str = str + "["+ str_var +"]"; 
			make_deserialize_member(attrlist[0],str);
			code += str;
			code += "}";

			str = code;
			break;
		}
	default:{	return;}
	}
}


As3Generate*
As3Generate::instance()
{
	static As3Generate g;
	return &g;
}

As3Generate::As3Generate():_directory("./rpc/")
{
	boost::filesystem::create_directory(_directory);
}

void 
As3Generate::make_code(Symbol *s)
{	
	switch(s->type())
	{
	case Enum:
		make_define_enum(s);
		break;
	case Struct:
		make_define_struct(s);
		break;
	case Interface:
		make_define_interface(s);
	default:

		break;
	}
}

void 
As3Generate::make_define_enum(Symbol *s)
{
	std::string file_name = s->name() + ".as";
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	_files.push_back(s->name());
	out<<"package rpc {\n";


	out<<"\tpublic class " << s->name().c_str() <<"{\n";
	for( size_t i=0 ; i<s->get_attrs().size(); ++i)
	{
		out<<"\t\t static public const "<<s->get_attrs()[i]->name().c_str()<<" : int = "<<i <<";\n";
	}
	out<<"\t};\n";

	out<<"}\n";
	out.close();
}

void
As3Generate::make_define_struct(Symbol *s)
{
	std::string file_name = s->name() + ".as";
	std::string target = _directory.string() + "/"+ file_name;

	std::ofstream out(target.c_str());
	_files.push_back(s->name());
	out<<"package rpc {\n";
	
	out<<"\tpublic class "<<s->name()<<"{\n";
	std::string members;
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i<attrlist.size(); ++i)
	{
		members += "\t\tpublic var ";
		std::string code;
		make_define_member(attrlist[i],code);
		members += code + ";\n\n";
	}	
	make_serialize(s , members);
	make_deserialize(s , members);
	out<<members;
	
	out<<"\t}\n";
	out<<"}\n";

	out.close();
}

void 
As3Generate::make_define_member(Symbol *s  , std::string &str)
{
	switch(s->type())
	{
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			make_define_member(attrlist[0] , str);
			str = s->name() + " : " + str;
			return;
		}
	case Custom:
		{
			str += s->name();
			str += " ";
			return;
		}
	case Boolean:
		{
			str += "Boolean ";
			return;
		}	
	case Int8:
		{
		}
	case Int16:
		{
		}
	case Int32:
		{
			str += "int ";
			break;
		}
	case Int64:
		{
			str += "Int64 ";
			return;
		}
	case UInt8:
		{
		}
	case UInt16:
		{
		}
	case UInt32:
		{
			str += "uint ";
			return;
		}
	case UInt64:
		{
			str += "UInt64 ";
			return;
		}
	case String:
		{
			str += "String ";
			return;
		}
	case Vector:
		{
			str += "Vector.< ";
			Symbol::AttrList const attrlist = s->get_attrs();
			make_define_member(attrlist[0] , str);
			str += " > ";
			return;
		}
	default:{	return;}
	}
}

void 
As3Generate::make_serialize(Symbol *s, std::string & str)
{
	str += "public function serialize( __writer__ : Object ) : void {";
	Symbol::AttrList const attrlist = s->get_attrs();

	std::string code ;
	for( size_t i=0 ; i<attrlist.size() ; ++i)
	{
		make_serialize_member(attrlist[i],code);
		str += code; 
		code = "";
	}
	str += "}\n";
}

void 
As3Generate::make_serialize_member(Symbol *s, std::string & str)
{

	switch(s->type())
	{
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();

			str += s->name();
			make_serialize_member(attrlist[0] , str);
			return;
		}
	case Custom:
		{
			str += ".serialize( __writer__ );";
			return;
		}
	case Boolean:
		{
			str = "__writer__.writeBoolean( " + str + " ) ;";
			return;
		}
	case Int8:
		{
			str = "__writer__.writeInt8( " + str + " ) ;";
			return;
		}
	case Int16:
		{
			str = "__writer__.writeInt16( " + str + " ) ;";
			return;
		}
	case Int32:
		{
			str = "__writer__.writeInt32( " + str + " ) ;";
			break;
		}
	case Int64:
		{
			str = "__writer__.writeInt64( " + str + " ) ;";
			return;
		}
	case UInt8:
		{
			str = "__writer__.writeUInt8( " + str + " ) ;";
			return;
		}
	case UInt16:
		{
			str = "__writer__.writeUInt16( " + str + " ) ;";
			return;
		}
	case UInt32:
		{
			str = "__writer__.writeUInt32( " + str + " ) ;";
			return;
		}
	case UInt64:
		{
			str = "__writer__.writeUInt64( " + str + " ) ;";
			return;
		}
	case String:
		{
			std::string code = "__writer__.writeUInt16( " + str + ".length );";
			code += "for( var i:int=0 ; i<" + str + ".length ; ++i ) { ";
			code += "__writer__.writeUInt8( " + str + "[i] ) ;}";
			str = code;
			return;
		}	
	case Vector:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			static int i = 0;
			char buff[64] = {'\0'};
			std::string str_var = std::string("_")+std::string(::itoa(i++,buff,2))+std::string("_");
			std::string code = "__writer__.writeUInt16( " + str + ".length );";
			code += "for( var " + str_var + " : int ; " + str_var + "<" + str + ".length ; ++" + str_var + ")";
			code += "{";
			str = str + "["+ str_var +"]"; 
			make_serialize_member(attrlist[0],str);
			code += str;
			code += "}";

			str = code;
			break;
		}
	default:{	return;}
	}
}


void 
As3Generate::make_deserialize(Symbol *s, std::string & str)
{
	str += "public function deserialize( __reader__ : Object ) : void {";
	Symbol::AttrList const attrlist = s->get_attrs();

	std::string code ;
	for( size_t i=0 ; i<attrlist.size() ; ++i)
	{
		make_deserialize_member(attrlist[i],code);
		str += code; 
		code = "";
	}
	str += "}\n";
}

void 
As3Generate::make_deserialize_member(Symbol *s, std::string & str)
{

	switch(s->type())
	{
	case Define:
		{
			Symbol::AttrList const attrlist = s->get_attrs();

			str += s->name();
			make_deserialize_member(attrlist[0] , str);
			return;
		}
	case Custom:
		{
			str += ".deserialize( __reader__ );";
			return;
		}
	case Boolean:
		{
			str += " = __reader__.readBoolean() ;";
			return;
		}
	case Int8:
		{
			str += " = __reader__.readInt8() ;";
			return;
		}
	case Int16:
		{
			str += " = __reader__.readInt16() ;";
			return;
		}
	case Int32:
		{
			str += " = __reader__.readInt32() ;";
			break;
		}
	case Int64:
		{
			str += " = __reader__.readInt64() ;";
			return;
		}
	case UInt8:
		{
			str += " = __reader__.readUInt8() ;";
			return;
		}
	case UInt16:
		{
			str += " = __reader__.readUInt16() ;";
			return;
		}
	case UInt32:
		{
			str += " = __reader__.readUInt32() ;";
			return;
		}
	case UInt64:
		{
			str += " = __reader__.readUInt64() ;";
			return;
		}
	case String:
		{
			std::string code = "var size : int = __reader__.readUInt16();";
			code += str + ".resize( size );";
			code += "for( var i : int=0 ; i<size ; ++i ) {";
			code += str + "[i] = __reader__.readUInt8() ;}";
			str = code;
			return;
		}	
	case Vector:
		{
			Symbol::AttrList const attrlist = s->get_attrs();
			static int i = 0;
			char buff[64] = {'\0'};
			std::string str_size = std::string("_size_") +std::string(::itoa(i++,buff,2)) + std::string("_");
			std::string str_var = std::string("_")+std::string(::itoa(i++,buff,2))+std::string("_");
			std::string code = std::string("var ") + str_size + " : int = __reader__.readUInt16();";
			code += str + ".resize(size)";
			code += "for( var " + str_var + " :int=0 ; " + str_var + "<"+ str_size +" ; ++" + str_var + " )";
			code += "{";
			str = str + "["+ str_var +"]"; 
			make_deserialize_member(attrlist[0],str);
			code += str;
			code += "}";

			str = code;
			break;
		}
	default:{	return;}
	}
}

void
As3Generate::make_define_interface(Symbol *s)
{
	make_proxy(s);
	make_stub(s);
}

void 
As3Generate::make_proxy(Symbol *s)
{
	std::string  proxy_name =  s->name() + "_proxy";
	std::string file_name =  proxy_name + ".as";
	_files.push_back(file_name);
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	out<<"package rpc {";
	out<<"\tpublic class "<< proxy_name << "{\n";
	
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i< attrlist.size(); ++i)
	{
		out<<"\t\tprivate const __"<<attrlist[i]->name()<<"__ : int = " << i <<";\n";
	}

	out<<"\t\tpublic function dispatch(__socket__ : Object) : void\n";
	out<<"\t\t{\n";
	out<<"\t\t\tvar __reader__ : Object = __socket__ ;\n";
	out<<"\t\t\tvar id : int = __reader__.readUint16();\n";
	out<<"\t\t\tswitch(id)\n";
	out<<"\t\t\t{\n";
	for(size_t i=0 ; i<attrlist.size(); ++i)
	{
		out<<"\t\t\t\tcase __"<<attrlist[i]->name().c_str()<<"__ :\n";
		out<<"\t\t\t\t{\n";
		Symbol::AttrList const paramlist = attrlist[i]->get_attrs();
		for(size_t j=1 ; j<paramlist.size(); ++j)
		{
			std::string str_def ;
			make_define_member(paramlist[j],str_def);
			out<<"\t\t\t\t\tvar "<<str_def<<"\n\n";
			std::string str_des;
			make_deserialize_member(paramlist[j],str_des);
			out<<"\t\t\t\t\t"<<str_des<<"\n\n";
		}

		out<<"\t\t\t\t\tthis."<<attrlist[i]->name()<<"( ";
		for(size_t j=1 ; j<paramlist.size(); ++j)
		{
			out<<paramlist[j]->name();
			if(j+1<paramlist.size())
			{
				out<<",";
			}
		}
		out<<" );\n";
		out<<"\t\t\t\t\tbreak;\n";
		out<<"\t\t\t\t}\n";
	}

	out<<"\t\t\t\tdefault:\n";
	out<<"\t\t\t\t{\n";
	out<<"\t\t\t\t\tbreak;\n";
	out<<"\t\t\t\t}\n";
	out<<"\t\t\t}\n";

	out<<"\t\t}\n";
	
	for (size_t i=0; i< attrlist.size(); ++i)
	{
		out<<"\t\tprotected function "<<attrlist[i]->name()<<"( ";
		Symbol::AttrList const paramlist = attrlist[i]->get_attrs();
		for(size_t j=1 ; j<paramlist.size(); ++j)
		{
			std::string str_def ;
			make_define_member(paramlist[j],str_def);
			if(j+1<paramlist.size())
			{
				str_def += ",";
			}
			out <<str_def;
		}
		out << " ) : void { throw new Error(\" proxy err \");};\n";
	}

	out<<"\t}\n";

	out<<"}\n";
	
	out.close();
}

void
As3Generate::make_stub(Symbol *s)
{
	std::string  stub_name = s->name() + "_stub";
	std::string file_name =  stub_name + ".as";
	_files.push_back(file_name);
	std::string target = _directory.string() + "/" + file_name;
	std::ofstream out(target.c_str());
	out<<"package rpc " <<"{\n";

	out<<"\tpublic class "<<stub_name<<"\n";
	out<<"\t{\n";
	Symbol::AttrList const attrlist = s->get_attrs();
	for (size_t i=0; i<attrlist.size();++i)
	{
		out<<"\t\tpublic function "<<attrlist[i]->name().c_str()<<"(";
		Symbol::AttrList const paramlist = attrlist[i]->get_attrs();
		for(size_t j=1;j<paramlist.size();++j)
		{
			std::string str_def;
			make_define_member(paramlist[j],str_def);
			out<<str_def;
			if(j+1<paramlist.size())
			{
				out<<",";
			}
		}
		out<<") : void \n";

		out<<"\t\t{\n";
		out<<"\t\t\tvar __writer__ : Object = _socket;\n";
		out<<"\t\t\t__writer__.writeUInt( "<< i <<" );\n";
		for(size_t j=1;j<paramlist.size();++j)
		{
			std::string str_def;
			make_serialize_member(paramlist[j],str_def);
			out<<"\t\t\t"<<str_def<<"\n";
		}
		out<<"\t\t}\n";

	}
	out<<"\t\tpublic function "<<stub_name.c_str()<<"(socket : Object){ _socket = socket ; }\n";
	out<<"\t\tprivate var _socket : Object;\n";
	out<<"\t}\n";
	out<<"}\n";
	out.close();
}
